home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / hplip / fax / pmlfax.py < prev    next >
Text File  |  2008-10-13  |  42KB  |  1,014 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Author: Don Welch
  20. #
  21.  
  22. # Std Lib
  23. import sys
  24. import os
  25. import os.path
  26. import struct
  27. import time
  28. import threading
  29.  
  30. # Local
  31. from base.g import *
  32. from base.codes import *
  33. from base import device, utils, pml, codes
  34. from prnt import cups
  35. from fax import *
  36.  
  37.  
  38. # **************************************************************************** #
  39.  
  40. # Page flags 
  41. PAGE_FLAG_NONE = 0x00
  42. PAGE_FLAG_NEW_PAGE = 0x01
  43. PAGE_FLAG_END_PAGE = 0x02
  44. PAGE_FLAG_NEW_DOC = 0x04
  45. PAGE_FLAG_END_DOC = 0x08
  46. PAGE_FLAG_END_STREAM = 0x10
  47.  
  48. MAJOR_VER = 2
  49. MINOR_VER = 0
  50.  
  51. MFPDTF_RASTER_BITMAP  = 0 # Not used
  52. MFPDTF_RASTER_GRAYMAP = 1 # Not used
  53. MFPDTF_RASTER_MH      = 2 # OfficeJets B&W Fax
  54. MFPDTF_RASTER_MR      = 3 # Not used
  55. MFPDTF_RASTER_MMR     = 4 # LaserJets B&W Fax
  56. MFPDTF_RASTER_RGB     = 5 # Not used
  57. MFPDTF_RASTER_YCC411  = 6 # Not used
  58. MFPDTF_RASTER_JPEG    = 7 # Color Fax
  59. MFPDTF_RASTER_PCL     = 8 # Not used
  60. MFPDTF_RASTER_NOT     = 9 # Not used
  61.  
  62. # Data types for FH
  63. DT_UNKNOWN       = 0
  64. DT_FAX_IMAGES    = 1
  65. DT_SCANNED_IMAGES= 2
  66. DT_DIAL_STRINGS  = 3
  67. DT_DEMO_PAGES    = 4
  68. DT_SPEED_DIALS   = 5
  69. DT_FAX_LOGS      = 6
  70. DT_CFG_PARMS     = 7
  71. DT_LANG_STRS     = 8
  72. DT_JUNK_FAX_CSIDS= 9  
  73. DT_REPORT_STRS   = 10  
  74. DT_FONTS         = 11
  75. DT_TTI_BITMAP    = 12
  76. DT_COUNTERS      = 13
  77. DT_DEF_PARMS     = 14  
  78. DT_SCAN_OPTIONS  = 15
  79. DT_FW_JOB_TABLE  = 17
  80.  
  81. # Raster data record types
  82. RT_START_PAGE = 0
  83. RT_RASTER = 1
  84. RT_END_PAGE = 2
  85.  
  86. # FH
  87. FIXED_HEADER_SIZE = 8
  88.  
  89. # Variants
  90. IMAGE_VARIANT_HEADER_SIZE = 10
  91. DIAL_STRINGS_VARIANT_HEADER_SIZE = 6
  92. FAX_IMAGE_VARIANT_HEADER_SIZE = 74
  93.  
  94. # Data records
  95. SOP_RECORD_SIZE = 36
  96. RASTER_RECORD_SIZE = 4
  97. EOP_RECORD_SIZE = 12
  98. DIAL_STRING_RECORD_SIZE = 51
  99.  
  100. # Page flags 
  101. PAGE_FLAG_NEW_PAGE = 0x01
  102. PAGE_FLAG_END_PAGE = 0x02
  103. PAGE_FLAG_NEW_DOC = 0x04
  104. PAGE_FLAG_END_DOC = 0x08
  105. PAGE_FLAG_END_STREAM = 0x10
  106.  
  107. # Fax data variant header data source
  108. SRC_UNKNOWN = 0
  109. SRC_HOST = 2
  110. SRC_SCANNER = 5
  111. SRC_HOST_THEN_SCANNER = 6
  112. SRC_SCANNER_THEN_HOST = 7
  113.  
  114. # Fax data variant header TTI header control
  115. TTI_NONE = 0
  116. TTI_PREPENDED_TO_IMAGE = 1
  117. TTI_OVERLAYED_ON_IMAGE = 2
  118.  
  119. RASTER_DATA_SIZE = 504
  120.  
  121.  
  122.  
  123. # **************************************************************************** #
  124. class PMLFaxDevice(FaxDevice):
  125.  
  126.     def __init__(self, device_uri=None, printer_name=None,
  127.                  callback=None, 
  128.                  fax_type=FAX_TYPE_NONE,
  129.                  disable_dbus=False):
  130.  
  131.         FaxDevice.__init__(self, device_uri, 
  132.                            printer_name, 
  133.                            callback, fax_type,
  134.                            disable_dbus)
  135.  
  136.         self.send_fax_thread = None
  137.         self.upload_log_thread = None
  138.         
  139.  
  140.     def setPhoneNum(self, num):
  141.         return self.setPML(pml.OID_FAX_LOCAL_PHONE_NUM, str(num))
  142.  
  143.     def getPhoneNum(self):
  144.         return utils.printable(str(self.getPML(pml.OID_FAX_LOCAL_PHONE_NUM)[1]))
  145.  
  146.     phone_num = property(getPhoneNum, setPhoneNum, doc="OID_FAX_LOCAL_PHONE_NUM")
  147.  
  148.  
  149.     def setStationName(self, name):
  150.         return self.setPML(pml.OID_FAX_STATION_NAME, str(name))
  151.  
  152.     def getStationName(self):
  153.         return utils.printable(str(self.getPML(pml.OID_FAX_STATION_NAME)[1]))
  154.  
  155.     station_name = property(getStationName, setStationName, doc="OID_FAX_STATION_NAME")
  156.  
  157.     def setDateAndTime(self):
  158.         t = time.localtime()
  159.         p = struct.pack("BBBBBBB", t[0]-2000, t[1], t[2], t[6]+1, t[3], t[4], t[5])
  160.         log.debug(repr(p))
  161.         return self.setPML(pml.OID_DATE_AND_TIME, p)
  162.  
  163.     def uploadLog(self):
  164.         if not self.isUloadLogActive():
  165.             self.upload_log_thread = UploadLogThread(self)
  166.             self.upload_log_thread.start()
  167.             return True
  168.         else:
  169.             return False
  170.  
  171.     def isUploadLogActive(self):
  172.         if self.upload_log_thread is not None:
  173.             return self.upload_log_thread.isAlive()
  174.         else:
  175.             return False
  176.  
  177.     def waitForUploadLogThread(self):
  178.         if self.upload_log_thread is not None and \
  179.             self.upload_log_thread.isAlive():
  180.  
  181.             self.upload_log_thread.join()
  182.  
  183.     def sendFaxes(self, phone_num_list, fax_file_list, cover_message='', cover_re='', 
  184.                   cover_func=None, preserve_formatting=False, printer_name='', 
  185.                   update_queue=None, event_queue=None):
  186.  
  187.         if not self.isSendFaxActive():
  188.     
  189.             self.send_fax_thread = PMLFaxSendThread(self, self.service, phone_num_list, fax_file_list, 
  190.                                                     cover_message, cover_re, cover_func, 
  191.                                                     preserve_formatting, 
  192.                                                     printer_name, update_queue, 
  193.                                                     event_queue)
  194.             
  195.             self.send_fax_thread.start()
  196.             return True
  197.         else:
  198.             return False
  199.  
  200.             
  201.             
  202. # **************************************************************************** #
  203. class PMLUploadLogThread(threading.Thread):
  204.     def __init__(self, dev):
  205.         threading.Thread.__init__(self)
  206.         self.dev = dev
  207.  
  208.  
  209.     def run(self):
  210.         STATE_DONE = 0
  211.         STATE_ABORT = 10
  212.         STATE_SUCCESS = 20
  213.         STATE_BUSY = 25
  214.         STATE_DEVICE_OPEN = 28
  215.         STATE_CHECK_IDLE = 30
  216.         STATE_REQUEST_START = 40
  217.         STATE_WAIT_FOR_ACTIVE = 50
  218.         STATE_UPLOAD_DATA = 60
  219.         STATE_DEVICE_CLOSE = 70
  220.  
  221.         state = STATE_CHECK_IDLE
  222.  
  223.         while state != STATE_DONE: # --------------------------------- Log upload state machine
  224.             if state == STATE_ABORT: 
  225.                 pass
  226.             elif state == STATE_SUCCESS:
  227.                 pass
  228.             elif state == STATE_BUSY:
  229.                 pass
  230.  
  231.             elif state == STATE_DEVICE_OPEN: # --------------------------------- Open device (28)
  232.                 state = STATE_REQUEST_START
  233.                 try:
  234.                     self.dev.open()
  235.                 except Error, e:
  236.                     log.error("Unable to open device (%s)." % e.msg)
  237.                     state = STATE_ERROR
  238.                 else:
  239.                     try:
  240.                         dev.setPML(pml.OID_UPLOAD_TIMEOUT, pml.DEFAULT_UPLOAD_TIMEOUT)
  241.                     except Error:
  242.                         state = STATE_ERROR
  243.  
  244.             elif state == STATE_CHECK_IDLE: # --------------------------------- Check idle (30)
  245.                 state = STATE_REQUEST_START
  246.                 ul_state = self.getCfgUploadState()
  247.  
  248.                 if ul_state != pml.UPDN_STATE_IDLE:
  249.                     state = STATE_BUSY
  250.  
  251.  
  252.             elif state == STATE_REQUEST_START: # --------------------------------- Request start (40)
  253.                 state = STATE_WAIT_FOR_ACTIVE
  254.                 self.dev.setPML(pml.OID_FAX_CFG_UPLOAD_DATA_TYPE, pml.FAX_CFG_UPLOAD_DATA_TYPE_FAXLOGS)
  255.                 self.dev.setPML(pml.OID_DEVICE_CFG_UPLOAD, pml.UPDN_STATE_REQSTART)
  256.  
  257.             elif state == STATE_WAIT_FOR_ACTIVE: # --------------------------------- Wait for active state (50)
  258.                 state = STATE_UPLOAD_DATA
  259.  
  260.                 tries = 0
  261.                 while True:
  262.                     tries += 1
  263.                     ul_state = self.getCfgUploadState()
  264.  
  265.                     if ul_state == pml.UPDN_STATE_XFERACTIVE:
  266.                         break
  267.  
  268.                     if ul_state in (pml.UPDN_STATE_ERRORABORT, pml.UPDN_STATE_XFERDONE):
  269.                         log.error("Cfg upload aborted!")
  270.                         state = STATE_ERROR
  271.                         break
  272.  
  273.                     if tries > 10:
  274.                         state = STATE_ERROR
  275.                         log.error("Unable to get into active state!")
  276.                         break
  277.  
  278.                     time.sleep(0.5)
  279.  
  280.             elif state == STATE_UPLOAD_DATA: # --------------------------------- Upload log data (60)
  281.                 pass
  282.  
  283.             elif state == STATE_DEVICE_CLOSE: # --------------------------------- Close device (70)
  284.                 self.dev.close()
  285.  
  286.  
  287.         
  288. # **************************************************************************** #
  289. class PMLFaxSendThread(FaxSendThread):
  290.     def __init__(self, dev, service, phone_num_list, fax_file_list, 
  291.                  cover_message='', cover_re='', cover_func=None, preserve_formatting=False,
  292.                  printer_name='', update_queue=None, event_queue=None):
  293.                  
  294.         FaxSendThread.__init__(self, dev, service, phone_num_list, fax_file_list, 
  295.              cover_message, cover_re, cover_func, preserve_formatting,
  296.              printer_name, update_queue, event_queue)
  297.  
  298.  
  299.     def run(self):
  300.         #results = {} # {'file' : error_code,...}
  301.  
  302.         STATE_DONE = 0
  303.         STATE_ABORTED = 10
  304.         STATE_SUCCESS = 20
  305.         STATE_BUSY = 25
  306.         STATE_READ_SENDER_INFO = 30
  307.         STATE_PRERENDER = 40
  308.         STATE_COUNT_PAGES = 50
  309.         STATE_NEXT_RECIPIENT = 60
  310.         STATE_COVER_PAGE = 70
  311.         STATE_SINGLE_FILE = 80
  312.         STATE_MERGE_FILES = 90
  313.         STATE_SINGLE_FILE = 100
  314.         STATE_SEND_FAX = 110
  315.         STATE_CLEANUP = 120
  316.         STATE_ERROR = 130
  317.  
  318.         next_recipient = self.next_recipient_gen()
  319.  
  320.         state = STATE_READ_SENDER_INFO
  321.         self.rendered_file_list = []
  322.  
  323.         while state != STATE_DONE: # --------------------------------- Fax state machine
  324.             if self.check_for_cancel():
  325.                 state = STATE_ABORTED
  326.  
  327.             log.debug("STATE=(%d, 0, 0)" % state)
  328.  
  329.             if state == STATE_ABORTED: # --------------------------------- Aborted (10, 0, 0)
  330.                 log.error("Aborted by user.")
  331.                 self.write_queue((STATUS_IDLE, 0, ''))
  332.                 state = STATE_CLEANUP
  333.  
  334.  
  335.             elif state == STATE_SUCCESS: # --------------------------------- Success (20, 0, 0)
  336.                 log.debug("Success.")
  337.                 self.write_queue((STATUS_COMPLETED, 0, ''))
  338.                 state = STATE_CLEANUP
  339.  
  340.  
  341.             elif state == STATE_ERROR: # --------------------------------- Error (130, 0, 0)
  342.                 log.error("Error, aborting.")
  343.                 self.write_queue((STATUS_ERROR, 0, ''))
  344.                 state = STATE_CLEANUP
  345.  
  346.  
  347.             elif state == STATE_BUSY: # --------------------------------- Busy (25, 0, 0)
  348.                 log.error("Device busy, aborting.")
  349.                 self.write_queue((STATUS_BUSY, 0, ''))
  350.                 state = STATE_CLEANUP
  351.  
  352.  
  353.             elif state == STATE_READ_SENDER_INFO: # --------------------------------- Get sender info (30, 0, 0)
  354.                 log.debug("%s State: Get sender info" % ("*"*20))
  355.                 state = STATE_PRERENDER
  356.                 try:
  357.                     try:
  358.                         self.dev.open()
  359.                     except Error, e:
  360.                         log.error("Unable to open device (%s)." % e.msg)
  361.                         state = STATE_ERROR
  362.                     else:
  363.                         try:
  364.                             self.sender_name = self.dev.station_name
  365.                             log.debug("Sender name=%s" % self.sender_name)
  366.                             self.sender_fax = self.dev.phone_num
  367.                             log.debug("Sender fax=%s" % self.sender_fax)
  368.                         except Error:
  369.                             log.error("PML get failed!")
  370.                             state = STATE_ERROR
  371.  
  372.                 finally:
  373.                     self.dev.close()
  374.  
  375.  
  376.             elif state == STATE_PRERENDER: # --------------------------------- Pre-render non-G3 files (40, 0, 0)
  377.                 log.debug("%s State: Pre-render non-G3 files" % ("*"*20))
  378.                 state = self.pre_render(STATE_COUNT_PAGES)
  379.                 
  380.  
  381.             elif state == STATE_COUNT_PAGES: # --------------------------------- Get total page count (50, 0, 0)
  382.                 log.debug("%s State: Get total page count" % ("*"*20))
  383.                 state = self.count_pages(STATE_NEXT_RECIPIENT)
  384.                 
  385.  
  386.             elif state == STATE_NEXT_RECIPIENT: # --------------------------------- Loop for multiple recipients (60, 0, 0)
  387.                 log.debug("%s State: Next recipient" % ("*"*20))
  388.                 state = STATE_COVER_PAGE
  389.  
  390.                 try:
  391.                     recipient = next_recipient.next()
  392.                     #print recipient
  393.                     log.debug("Processing for recipient %s" % recipient['name'])
  394.                 except StopIteration:
  395.                     state = STATE_SUCCESS
  396.                     log.debug("Last recipient.")
  397.                     continue
  398.  
  399.                 self.recipient_file_list = self.rendered_file_list[:]
  400.  
  401.  
  402.             elif state == STATE_COVER_PAGE: # --------------------------------- Create cover page (70, 0, 0)
  403.                 log.debug("%s State: Render cover page" % ("*"*20))
  404.                 state = self.cover_page(recipient)
  405.  
  406.  
  407.             elif state == STATE_SINGLE_FILE: # --------------------------------- Special case for single file (no merge) (80, 0, 0)
  408.                 log.debug("%s State: Handle single file" % ("*"*20))
  409.                 state = self.single_file(STATE_SEND_FAX)
  410.  
  411.             elif state == STATE_MERGE_FILES: # --------------------------------- Merge multiple G3 files (90, 0, 0)
  412.                 log.debug("%s State: Merge multiple files" % ("*"*20))
  413.                 state = self.merge_files(STATE_SEND_FAX)
  414.  
  415.             elif state == STATE_SEND_FAX: # --------------------------------- Send fax state machine (110, 0, 0)
  416.                 log.debug("%s State: Send fax" % ("*"*20))
  417.                 state = STATE_NEXT_RECIPIENT
  418.  
  419.                 FAX_SEND_STATE_DONE = 0
  420.                 FAX_SEND_STATE_ABORT = 10
  421.                 FAX_SEND_STATE_ERROR = 20
  422.                 FAX_SEND_STATE_BUSY = 25
  423.                 FAX_SEND_STATE_SUCCESS = 30
  424.                 FAX_SEND_STATE_DEVICE_OPEN = 40
  425.                 FAX_SEND_STATE_SET_TOKEN = 50
  426.                 FAX_SEND_STATE_EARLY_OPEN = 60
  427.                 FAX_SEND_STATE_SET_PARAMS = 70
  428.                 FAX_SEND_STATE_CHECK_IDLE = 80
  429.                 FAX_SEND_STATE_START_REQUEST = 90
  430.                 FAX_SEND_STATE_LATE_OPEN = 100
  431.                 FAX_SEND_STATE_SEND_DIAL_STRINGS = 110
  432.                 FAX_SEND_STATE_SEND_FAX_HEADER = 120
  433.                 FAX_SEND_STATE_SEND_PAGES = 130
  434.                 FAX_SEND_STATE_SEND_END_OF_STREAM = 140
  435.                 FAX_SEND_STATE_WAIT_FOR_COMPLETE = 150
  436.                 FAX_SEND_STATE_RESET_TOKEN = 160
  437.                 FAX_SEND_STATE_CLOSE_SESSION = 170
  438.  
  439.                 monitor_state = False
  440.                 fax_send_state = FAX_SEND_STATE_DEVICE_OPEN
  441.  
  442.                 while fax_send_state != FAX_SEND_STATE_DONE:
  443.  
  444.                     if self.check_for_cancel():
  445.                         log.error("Fax send aborted.")
  446.                         fax_send_state = FAX_SEND_STATE_ABORT
  447.  
  448.                     if monitor_state:
  449.                         fax_state = self.getFaxDownloadState() 
  450.                         if not fax_state in (pml.UPDN_STATE_XFERACTIVE, pml.UPDN_STATE_XFERDONE):
  451.                             log.error("D/L error state=%d" % fax_state)
  452.                             fax_send_state = FAX_SEND_STATE_ERROR
  453.                             state = STATE_ERROR
  454.  
  455.                     log.debug("STATE=(%d, %d, 0)" % (STATE_SEND_FAX, fax_send_state))
  456.  
  457.                     if fax_send_state == FAX_SEND_STATE_ABORT: # -------------- Abort (110, 10, 0)
  458.                         # TODO: Set D/L state to ???
  459.                         monitor_state = False
  460.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  461.                         state = STATE_ABORTED
  462.  
  463.                     elif fax_send_state == FAX_SEND_STATE_ERROR: # -------------- Error (110, 20, 0)
  464.                         log.error("Fax send error.")
  465.                         monitor_state = False
  466.  
  467.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  468.                         state = STATE_ERROR
  469.  
  470.                     elif fax_send_state == FAX_SEND_STATE_BUSY: # -------------- Busy (110, 25, 0)
  471.                         log.error("Fax device busy.")
  472.                         monitor_state = False
  473.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  474.                         state = STATE_BUSY
  475.  
  476.                     elif fax_send_state == FAX_SEND_STATE_SUCCESS: # -------------- Success (110, 30, 0)
  477.                         log.debug("Fax send success.")
  478.                         monitor_state = False
  479.                         fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  480.                         state = STATE_NEXT_RECIPIENT
  481.  
  482.                     elif fax_send_state == FAX_SEND_STATE_DEVICE_OPEN: # -------------- Device open (110, 40, 0)
  483.                         log.debug("%s State: Open device" % ("*"*20))
  484.                         fax_send_state = FAX_SEND_STATE_SET_TOKEN
  485.                         try:
  486.                             self.dev.open()
  487.                         except Error, e:
  488.                             log.error("Unable to open device (%s)." % e.msg)
  489.                             fax_send_state = FAX_SEND_STATE_ERROR
  490.                         else:
  491.                             if self.dev.device_state == DEVICE_STATE_NOT_FOUND:
  492.                                 fax_send_state = FAX_SEND_STATE_ERROR
  493.  
  494.                     elif fax_send_state == FAX_SEND_STATE_SET_TOKEN: # -------------- Acquire fax token (110, 50, 0)
  495.                         log.debug("%s State: Acquire fax token" % ("*"*20))
  496.                         try:
  497.                             result_code, token = self.dev.getPML(pml.OID_FAX_TOKEN)
  498.                         except Error:
  499.                             log.debug("Unable to acquire fax token (1).")
  500.                             fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  501.                         else:
  502.                             if result_code > pml.ERROR_MAX_OK:
  503.                                 fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  504.                                 log.debug("Skipping token acquisition.")
  505.                             else:
  506.                                 token = time.strftime("%d%m%Y%H:%M:%S", time.gmtime())
  507.                                 log.debug("Setting token: %s" % token)
  508.                                 try:
  509.                                     self.dev.setPML(pml.OID_FAX_TOKEN, token)
  510.                                 except Error:
  511.                                     log.error("Unable to acquire fax token (2).")
  512.                                     fax_send_state = FAX_SEND_STATE_ERROR
  513.                                 else:
  514.                                     result_code, check_token = self.dev.getPML(pml.OID_FAX_TOKEN)
  515.  
  516.                                     if check_token == token:
  517.                                         fax_send_state = FAX_SEND_STATE_EARLY_OPEN
  518.                                     else:
  519.                                         log.error("Unable to acquire fax token (3).")
  520.                                         fax_send_state = FAX_SEND_STATE_ERROR
  521.  
  522.  
  523.                     elif fax_send_state == FAX_SEND_STATE_EARLY_OPEN: # -------------- Early open (newer models) (110, 60, 0)
  524.                         log.debug("%s State: Early open" % ("*"*20))
  525.                         fax_send_state = FAX_SEND_STATE_CHECK_IDLE
  526.  
  527.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN: # newer
  528.                             log.debug("Opening fax channel.")
  529.                             try:
  530.                                 self.dev.openFax()
  531.                             except Error, e:
  532.                                 log.error("Unable to open channel (%s)." % e.msg)
  533.                                 fax_send_state = FAX_SEND_STATE_ERROR
  534.                         else:
  535.                             log.debug("Skipped.")
  536.  
  537.  
  538.                     elif fax_send_state == FAX_SEND_STATE_CHECK_IDLE: # -------------- Check for initial idle (110, 80, 0)
  539.                         log.debug("%s State: Check idle" % ("*"*20))
  540.                         fax_send_state = FAX_SEND_STATE_START_REQUEST
  541.  
  542.                         dl_state = self.getFaxDownloadState()
  543.                         tx_status = self.getFaxJobTxStatus()
  544.                         rx_status = self.getFaxJobRxStatus()
  545.  
  546.                         if ((dl_state == pml.UPDN_STATE_IDLE or \
  547.                             dl_state == pml.UPDN_STATE_ERRORABORT or \
  548.                             dl_state == pml.UPDN_STATE_XFERDONE) and \
  549.                             (tx_status == pml.FAXJOB_TX_STATUS_IDLE or tx_status == pml.FAXJOB_TX_STATUS_DONE) and \
  550.                             (rx_status == pml.FAXJOB_RX_STATUS_IDLE or rx_status == pml.FAXJOB_RX_STATUS_DONE)):
  551.  
  552.                             # xwas if state == pml.UPDN_STATE_IDLE:
  553.                             if dl_state == pml.UPDN_STATE_IDLE:
  554.                                 log.debug("Starting in idle state")
  555.                             else:
  556.                                 log.debug("Resetting to idle...")
  557.                                 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE)
  558.                                 time.sleep(0.5)
  559.                         else:
  560.                             fax_send_state = FAX_SEND_STATE_BUSY
  561.  
  562.                     elif fax_send_state == FAX_SEND_STATE_START_REQUEST: # -------------- Request fax start (110, 90, 0) 
  563.                         log.debug("%s State: Request start" % ("*"*20))
  564.                         fax_send_state = FAX_SEND_STATE_SET_PARAMS
  565.  
  566.                         dl_state = self.getFaxDownloadState()
  567.  
  568.                         if dl_state == pml.UPDN_STATE_IDLE:
  569.                             log.debug("Try: 0")
  570.                             log.debug("Setting to up/down state request start...")
  571.                             self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART)
  572.                             time.sleep(1)
  573.  
  574.                             log.debug("Waiting for active state...")
  575.                             i = 1
  576.  
  577.                             while i < 10:
  578.                                 log.debug("Try: %d" % i)
  579.                                 try:
  580.                                     dl_state = self.getFaxDownloadState()
  581.                                 except Error:
  582.                                     log.error("PML/SNMP error")
  583.                                     fax_send_state = FAX_SEND_STATE_ERROR
  584.                                     break
  585.  
  586.                                 if dl_state == pml.UPDN_STATE_XFERACTIVE:
  587.                                     break
  588.  
  589.                                 time.sleep(1)
  590.                                 log.debug("Setting to up/down state request start...")
  591.                                 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART)
  592.  
  593.                                 i += 1
  594.  
  595.                             else:  
  596.                                 log.error("Could not get into active state!")
  597.                                 fax_send_state = FAX_SEND_STATE_BUSY
  598.  
  599.                             monitor_state = True
  600.  
  601.                         else:
  602.                             log.error("Could not get into idle state!")
  603.                             fax_send_state = FAX_SEND_STATE_BUSY
  604.  
  605.  
  606.                     elif fax_send_state == FAX_SEND_STATE_SET_PARAMS: # -------------- Set fax send params (110, 70, 0)
  607.                         log.debug("%s State: Set params" % ("*"*20))
  608.                         fax_send_state = FAX_SEND_STATE_LATE_OPEN
  609.  
  610.                         try:
  611.                             self.dev.setPML(pml.OID_DEV_DOWNLOAD_TIMEOUT, pml.DEFAULT_DOWNLOAD_TIMEOUT)
  612.                             self.dev.setPML(pml.OID_FAXJOB_TX_TYPE, pml.FAXJOB_TX_TYPE_HOST_ONLY)
  613.                             log.debug("Setting date and time on device.")                            
  614.                             self.dev.setDateAndTime() 
  615.                         except Error, e:
  616.                             log.error("PML/SNMP error (%s)" % e.msg)
  617.                             fax_send_state = FAX_SEND_STATE_ERROR
  618.  
  619.  
  620.                     elif fax_send_state == FAX_SEND_STATE_LATE_OPEN: # -------------- Late open (older models) (110, 100, 0)
  621.                         log.debug("%s State: Late open" % ("*"*20))
  622.                         fax_send_state = FAX_SEND_STATE_SEND_DIAL_STRINGS
  623.  
  624.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN: # older
  625.                             log.debug("Opening fax channel.")
  626.                             try:
  627.                                 self.dev.openFax()
  628.                             except Error:
  629.                                 log.error("Unable to open channel.")
  630.                                 fax_send_state = FAX_SEND_STATE_ERROR
  631.                         else:
  632.                             log.debug("Skipped.")
  633.  
  634.  
  635.                     elif fax_send_state == FAX_SEND_STATE_SEND_DIAL_STRINGS: # -------------- Dial strings (110, 110, 0)
  636.                         log.debug("%s State: Send dial strings" % ("*"*20))
  637.                         fax_send_state = FAX_SEND_STATE_SEND_FAX_HEADER
  638.  
  639.                         log.debug("Dialing: %s" % recipient['fax'])
  640.  
  641.                         log.debug("Sending dial strings...")
  642.                         self.create_mfpdtf_fixed_header(DT_DIAL_STRINGS, True, 
  643.                             PAGE_FLAG_NEW_DOC | PAGE_FLAG_END_DOC | PAGE_FLAG_END_STREAM) # 0x1c on Windows, we were sending 0x0c
  644.                         #print recipient
  645.                         dial_strings = recipient['fax'].encode('ascii')
  646.                         log.debug(repr(dial_strings))
  647.                         self.create_mfpdtf_dial_strings(dial_strings)
  648.  
  649.                         try:
  650.                             self.write_stream()
  651.                         except Error:
  652.                             log.error("Channel write error.")
  653.                             fax_send_state = FAX_SEND_STATE_ERROR
  654.  
  655.  
  656.                     elif fax_send_state == FAX_SEND_STATE_SEND_FAX_HEADER: # -------------- Fax header (110, 120, 0)
  657.                         log.debug("%s State: Send fax header" % ("*"*20))
  658.                         fax_send_state = FAX_SEND_STATE_SEND_PAGES
  659.  
  660.                         try:
  661.                             ff = file(self.f, 'r')
  662.                         except IOError:
  663.                             log.error("Unable to read fax file.")
  664.                             fax_send_state = FAX_SEND_STATE_ERROR
  665.                             continue
  666.  
  667.                         try:
  668.                             header = ff.read(FILE_HEADER_SIZE)
  669.                         except IOError:
  670.                             log.error("Unable to read fax file.")
  671.                             fax_send_state = FAX_SEND_STATE_ERROR
  672.                             continue
  673.  
  674.                         magic, version, total_pages, hort_dpi, vert_dpi, page_size, \
  675.                             resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header)
  676.  
  677.                         if magic != 'hplip_g3':
  678.                             log.error("Invalid file header. Bad magic.")
  679.                             fax_send_state = FAX_SEND_STATE_ERROR
  680.                         else:
  681.                             log.debug("Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d" %
  682.                                       (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding))
  683.  
  684.                             log.debug("Sending fax header...")
  685.                             self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, True, PAGE_FLAG_NEW_DOC)
  686.                             self.create_mfpdtf_fax_header(total_pages)
  687.  
  688.                             try:
  689.                                 self.write_stream()
  690.                             except Error:
  691.                                 log.error("Unable to write to channel.")
  692.                                 fax_send_state = FAX_SEND_STATE_ERROR
  693.  
  694.  
  695.                     elif fax_send_state == FAX_SEND_STATE_SEND_PAGES:  # --------------------------------- Send fax pages state machine (110, 130, 0)
  696.                         log.debug("%s State: Send pages" % ("*"*20))
  697.                         fax_send_state = FAX_SEND_STATE_SEND_END_OF_STREAM
  698.                         page = StringIO()
  699.  
  700.                         for p in range(total_pages):
  701.  
  702.                             if self.check_for_cancel():
  703.                                 fax_send_state = FAX_SEND_STATE_ABORT
  704.  
  705.                             if fax_send_state == FAX_SEND_STATE_ABORT:
  706.                                 break
  707.  
  708.                             try:
  709.                                 header = ff.read(PAGE_HEADER_SIZE)
  710.                             except IOError:
  711.                                 log.error("Unable to read fax file.")
  712.                                 fax_send_state = FAX_SEND_STATE_ERROR
  713.                                 continue
  714.  
  715.                             page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, reserved2 = \
  716.                                 self.decode_page_header(header)
  717.  
  718.                             log.debug("Page=%d PPR=%d RPP=%d BPP=%d Thumb=%d" %
  719.                                       (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes))
  720.  
  721.                             page.write(ff.read(bytes_to_read))
  722.                             thumbnail = ff.read(thumbnail_bytes) # thrown away for now (should be 0 read)
  723.                             page.seek(0)
  724.  
  725.                             self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags=PAGE_FLAG_NEW_PAGE)
  726.                             self.create_sop_record(page_num, hort_dpi, vert_dpi, ppr, rpp, encoding)
  727.  
  728.                             try:
  729.                                 data = page.read(RASTER_DATA_SIZE)
  730.                             except IOError:
  731.                                 log.error("Unable to read fax file.")
  732.                                 fax_send_state = FAX_SEND_STATE_ERROR
  733.                                 continue
  734.  
  735.                             if data == '':
  736.                                 log.error("No data!")
  737.                                 fax_send_state = FAX_SEND_STATE_ERROR
  738.                                 continue
  739.  
  740.                             self.create_raster_data_record(data)
  741.                             total_read = RASTER_DATA_SIZE
  742.  
  743.                             while True:
  744.                                 data = page.read(RASTER_DATA_SIZE)
  745.                                 total_read += RASTER_DATA_SIZE
  746.  
  747.                                 self.getFaxDownloadState()
  748.  
  749.                                 if data == '':
  750.                                     self.create_eop_record(rpp)
  751.  
  752.                                     try:
  753.                                         self.write_stream()
  754.                                     except Error:
  755.                                         log.error("Channel write error.")
  756.                                         fax_send_state = FAX_SEND_STATE_ERROR
  757.                                     break
  758.  
  759.                                 else:
  760.                                     try:
  761.                                         self.write_stream()
  762.                                     except Error:
  763.                                         log.error("Channel write error.")
  764.                                         fax_send_state = FAX_SEND_STATE_ERROR
  765.                                         break
  766.  
  767.                                 status = self.getFaxJobTxStatus()
  768.                                 while status  == pml.FAXJOB_TX_STATUS_DIALING:
  769.                                     self.write_queue((STATUS_DIALING, 0, recipient['fax']))
  770.                                     time.sleep(1.0)
  771.  
  772.                                     if self.check_for_cancel():
  773.                                         fax_send_state = FAX_SEND_STATE_ABORT
  774.                                         break
  775.  
  776.                                     dl_state = self.getFaxDownloadState()
  777.                                     if dl_state == pml.UPDN_STATE_ERRORABORT:
  778.                                         fax_send_state = FAX_SEND_STATE_ERROR
  779.                                         break
  780.  
  781.                                     status = self.getFaxJobTxStatus()
  782.  
  783.                                 if fax_send_state not in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR):
  784.  
  785.                                     while status  == pml.FAXJOB_TX_STATUS_CONNECTING: 
  786.                                         self.write_queue((STATUS_CONNECTING, 0, recipient['fax']))
  787.                                         time.sleep(1.0)
  788.  
  789.                                         if self.check_for_cancel():
  790.                                             fax_send_state = FAX_SEND_STATE_ABORT
  791.                                             break
  792.  
  793.                                         dl_state = self.getFaxDownloadState()
  794.                                         if dl_state == pml.UPDN_STATE_ERRORABORT:
  795.                                             fax_send_state = FAX_SEND_STATE_ERROR
  796.                                             break
  797.  
  798.                                         status = self.getFaxJobTxStatus()
  799.  
  800.                                 if status == pml.FAXJOB_TX_STATUS_TRANSMITTING:    
  801.                                     self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
  802.  
  803.                                 self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags=0)
  804.                                 self.create_raster_data_record(data)
  805.  
  806.                                 if fax_send_state in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR):
  807.                                     break
  808.  
  809.                             page.truncate(0)
  810.                             page.seek(0)                
  811.  
  812.  
  813.                     elif fax_send_state == FAX_SEND_STATE_SEND_END_OF_STREAM: # -------------- EOS (110, 140, 0)
  814.                         log.debug("%s State: Send EOS" % ("*"*20))
  815.                         fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE
  816.                         log.debug("End of stream...")
  817.                         self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, False, PAGE_FLAG_END_STREAM)
  818.  
  819.                         try:
  820.                             self.write_stream()
  821.                         except Error:
  822.                             log.error("Channel write error.")
  823.                             fax_send_state = FAX_SEND_STATE_ERROR
  824.  
  825.                         monitor_state = False
  826.  
  827.  
  828.                     elif fax_send_state == FAX_SEND_STATE_WAIT_FOR_COMPLETE: # -------------- Wait for complete (110, 150, 0)
  829.                         log.debug("%s State: Wait for completion" % ("*"*20))
  830.  
  831.                         fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE
  832.  
  833.                         time.sleep(1.0)
  834.                         status = self.getFaxJobTxStatus()
  835.  
  836.                         if status == pml.FAXJOB_TX_STATUS_DIALING:
  837.                                 self.write_queue((STATUS_DIALING, 0, recipient['fax']))
  838.                                 log.debug("Dialing ...")
  839.  
  840.                         elif status == pml.FAXJOB_TX_STATUS_TRANSMITTING:    
  841.                             self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
  842.                             log.debug("Transmitting ...")
  843.  
  844.                         elif status in (pml.FAXJOB_TX_STATUS_DONE, pml.FAXJOB_RX_STATUS_IDLE):
  845.                             fax_send_state = FAX_SEND_STATE_RESET_TOKEN
  846.                             state = STATE_NEXT_RECIPIENT
  847.                             log.debug("Transmitting done or idle ...")
  848.  
  849.                         else:
  850.                             self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
  851.                             log.debug("Pending ...")
  852.  
  853.  
  854.                     elif fax_send_state == FAX_SEND_STATE_RESET_TOKEN: # -------------- Release fax token (110, 160, 0)
  855.                         self.write_queue((STATUS_CLEANUP, 0, ''))
  856.                         log.debug("%s State: Release fax token" % ("*"*20))
  857.  
  858.                         try:
  859.                             self.dev.setPML(pml.OID_FAX_TOKEN, '\x00'*16)
  860.                         except Error:
  861.                             log.error("Unable to release fax token.")
  862.  
  863.                         fax_send_state = FAX_SEND_STATE_CLOSE_SESSION
  864.  
  865.  
  866.                     elif fax_send_state == FAX_SEND_STATE_CLOSE_SESSION: # -------------- Close session (110, 170, 0)
  867.                         log.debug("%s State: Close session" % ("*"*20))
  868.                         fax_send_state = FAX_SEND_STATE_DONE
  869.                         log.debug("Closing session...")
  870.  
  871.                         try:
  872.                             mm.close()
  873.                         except NameError:
  874.                             pass
  875.  
  876.                         try:
  877.                             ff.close()
  878.                         except NameError:
  879.                             pass
  880.  
  881.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN:
  882.                             log.debug("Closing fax channel.")
  883.                             self.dev.closeFax()
  884.  
  885.                         self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE)
  886.  
  887.                         time.sleep(1)
  888.  
  889.                         if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN:
  890.                             log.debug("Closing fax channel.")
  891.                             self.dev.closeFax()
  892.  
  893.                         self.dev.close()
  894.  
  895.  
  896.             elif state == STATE_CLEANUP: # --------------------------------- Cleanup (120, 0, 0)
  897.                 log.debug("%s State: Cleanup" % ("*"*20))
  898.  
  899.                 if self.remove_temp_file:
  900.                     log.debug("Removing merged file: %s" % self.f)
  901.                     try:
  902.                         os.remove(self.f)
  903.                         log.debug("Removed")
  904.                     except OSError:
  905.                         log.debug("Not found")
  906.  
  907.                 state = STATE_DONE
  908.  
  909.  
  910.  
  911. # --------------------------------- Support functions
  912.  
  913.  
  914.     def getFaxDownloadState(self):
  915.         result_code, state = self.dev.getPML(pml.OID_FAX_DOWNLOAD)
  916.         if state:
  917.             log.debug("D/L State=%d (%s)" % (state, pml.UPDN_STATE_STR.get(state, 'Unknown')))
  918.             return state
  919.         else:
  920.             return pml.UPDN_STATE_ERRORABORT
  921.  
  922.     def getFaxJobTxStatus(self):
  923.         result_code, status = self.dev.getPML(pml.OID_FAXJOB_TX_STATUS)
  924.         if status:
  925.             log.debug("Tx Status=%d (%s)" % (status, pml.FAXJOB_TX_STATUS_STR.get(status, 'Unknown')))
  926.             return status
  927.         else:
  928.             return pml.FAXJOB_TX_STATUS_IDLE
  929.  
  930.     def getFaxJobRxStatus(self):
  931.         result_code, status = self.dev.getPML(pml.OID_FAXJOB_RX_STATUS)
  932.         if status:
  933.             log.debug("Rx Status=%d (%s)" % (status, pml.FAXJOB_RX_STATUS_STR.get(status, 'Unknown')))
  934.             return status
  935.         else:
  936.             return pml.FAXJOB_RX_STATUS_IDLE
  937.  
  938.     def getCfgUploadState(self):
  939.         result_code, state = self.dev.getPML(pml.OID_DEVICE_CFG_UPLOAD)
  940.         if state:
  941.             log.debug("Cfg Upload State = %d (%s)" % (state, pml.UPDN_STATE_STR.get(state, 'Unknown')))
  942.             return state
  943.         else:
  944.             return pml.UPDN_STATE_ERRORABORT
  945.  
  946.     def create_mfpdtf_fixed_header(self, data_type, send_variant=False, page_flags=0):
  947.         header_len = FIXED_HEADER_SIZE
  948.  
  949.         if send_variant:
  950.             if data_type == DT_DIAL_STRINGS:
  951.                     header_len += DIAL_STRINGS_VARIANT_HEADER_SIZE
  952.  
  953.             elif data_type == DT_FAX_IMAGES:
  954.                 header_len += FAX_IMAGE_VARIANT_HEADER_SIZE
  955.  
  956.         self.stream.write(struct.pack("<IHBB", 
  957.                           0, header_len, data_type, page_flags))
  958.  
  959.  
  960.     def create_mfpdtf_dial_strings(self, number):
  961.         p = struct.pack("<BBHH51s", 
  962.                           MAJOR_VER, MINOR_VER,
  963.                           1, 51, number[:51])
  964.         log.debug(repr(p))
  965.         self.stream.write(p)
  966.  
  967.  
  968.     def adjust_fixed_header_block_size(self):
  969.         size = self.stream.tell()
  970.         self.stream.seek(0)
  971.         self.stream.write(struct.pack("<I", size))
  972.  
  973.  
  974.     def create_sop_record(self, page_num, hort_dpi, vert_dpi, ppr, rpp, encoding, bpp=1):
  975.         self.stream.write(struct.pack("<BBHHHIHHHHHHIHHHH",
  976.                             RT_START_PAGE, encoding, page_num,
  977.                             ppr, bpp,
  978.                             rpp, 0x00, hort_dpi, 0x00, vert_dpi,
  979.                             ppr, bpp,
  980.                             rpp, 0x00, hort_dpi, 0x00, vert_dpi))
  981.  
  982.  
  983.     def create_eop_record(self, rpp):
  984.         self.stream.write(struct.pack("<BBBBII",
  985.                             RT_END_PAGE, 0, 0, 0, 
  986.                             rpp, 0,))
  987.  
  988.  
  989.     def create_raster_data_record(self, data):
  990.         assert len(data) <= RASTER_DATA_SIZE
  991.         self.stream.write(struct.pack("<BBH",
  992.                         RT_RASTER, 0, len(data),))
  993.         self.stream.write(data)
  994.  
  995.  
  996.     def create_mfpdtf_fax_header(self, total_pages):
  997.         self.stream.write(struct.pack("<BBBHBI20s20s20sI", 
  998.                             MAJOR_VER, MINOR_VER, SRC_HOST, total_pages, 
  999.                             TTI_PREPENDED_TO_IMAGE, 0, '', '', '', 0))
  1000.  
  1001.  
  1002.     def write_stream(self):
  1003.         self.adjust_fixed_header_block_size() 
  1004.         self.dev.writeFax(self.stream.getvalue())
  1005.         self.stream.truncate(0)
  1006.         self.stream.seek(0)    
  1007.  
  1008.  
  1009.  
  1010.             
  1011.             
  1012.             
  1013.   
  1014.